home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************
- Module name: DFServer.C
- Programmer : Jeffrey M. Richter.
- Description: Drop File Server Sample Application.
- *****************************************************************************/
-
- #include <windows.h>
- #include <shellapi.h>
- #include <commdlg.h>
- #include <string.h>
-
- #include "DFServer.h"
-
- //************ PROTOTYPES FOR FILE OPEN UTILITY FUNCTION ********************/
- WORD FAR GetSinglePathName (LPCSTR szFileOpenStr, WORD wIndex,
- LPSTR szPathName, WORD wMaxLen);
-
-
- //************ PROTOTYPES FOR DROP-FILE SERVER FUNCTIONS ********************/
- HDROP FAR DragCreateFiles (LPPOINT lpptMousePos, BOOL fInNonClientArea);
- HDROP FAR DragAppendFile (HDROP hDrop, LPCSTR szPathname);
-
-
- //****************** PROTOTYPES FOR LOCAL FUNCTIONS *************************/
- LRESULT FAR WndProc (HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
- #define UM_UPDATECAPTION (WM_USER + 0) // wParam is number of files
-
- //************************ GLOBAL VARIABLES *********************************/
- char _szAppName[] = "Drop File Server";
- extern _cdecl HINSTANCE _hInstance;
-
-
- #pragma argsused
- int WinMain (HANDLE hInstance, HANDLE hPrevInstance,
- LPSTR lpszCmdLine, int nCmdShow) {
-
- MSG msg;
- HWND hWnd;
- WNDCLASS wc;
-
- if (hPrevInstance == NULL) {
- wc.style = 0;
- wc.lpfnWndProc = (WNDPROC) WndProc;
- wc.cbClsExtra = wc.cbWndExtra = 0;
- _hInstance = wc.hInstance = hInstance;
- wc.hIcon = LoadIcon(hInstance, "DropFile");
- wc.hCursor = LoadCursor(NULL, IDC_UPARROW);
- wc.hbrBackground = COLOR_GRAYTEXT + 1;
- wc.lpszMenuName = "DROPFILE";
- wc.lpszClassName = _szAppName;
- if (!RegisterClass(&wc)) return(0);
- }
-
- // Create the Frame window.
- // The WS_EXACCEPTFILES style is not needed for server-only apps.
- hWnd = CreateWindow(_szAppName, _szAppName,
- WS_OVERLAPPED | WS_VISIBLE | WS_CAPTION | WS_THICKFRAME |
- WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX,
- CW_USEDEFAULT, nCmdShow,
- GetSystemMetrics(SM_CXSCREEN) / 2, // 1/2-screen width
- GetSystemMetrics(SM_CYSCREEN) / 8, // 1/8-screen height
- NULL, NULL, hInstance, NULL);
- if (hWnd == NULL) return(0);
-
- while (GetMessage(&msg, NULL, 0, 0)) {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- return(msg.wParam);
- }
-
-
- LRESULT FAR WndProc (HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
- static char szAllFileNames[1000] = { 0 };
- HCURSOR hCrsrDrpNotAllow, hCrsrDrpSingle, hCrsrDrpMultiple;
- char szBuf[100], szDropPathName[200];
- BOOL fCallDefProc = FALSE, fInNonClientArea, fOkToDrop;
- LONG lResult = 0;
- POINT ptMousePos;
- WORD x, wNumFiles;
- HWND hWndSubject;
- HDROP hDrop, hDropT;
- OPENFILENAME ofn;
-
-
- switch (Msg) {
- case WM_CREATE:
- SendMessage(hWnd, UM_UPDATECAPTION, 0, 0);
- break;
-
- case WM_DESTROY:
- // Terminate the application
- PostQuitMessage(0);
- break;
-
- case WM_COMMAND:
- if (wParam != IDM_FILESELECT) {
- fCallDefProc = TRUE;
- break;
- }
-
- // Initialize structure for calling
- // the "Open File" common dialog
- _fmemset(&ofn, 0, sizeof(ofn));
- ofn.lStructSize = sizeof(ofn);
- ofn.hwndOwner = hWnd;
- ofn.lpstrFilter = "All files\0*.*\0";
- ofn.Flags = OFN_ALLOWMULTISELECT | OFN_FILEMUSTEXIST |
- OFN_HIDEREADONLY;
-
- // Set up the buffer to receive the selected file(s)
- szAllFileNames[0] = 0;
- ofn.lpstrFile = szAllFileNames;
- ofn.nMaxFile = sizeof(szAllFileNames);
-
- if (GetOpenFileName(&ofn))
- wNumFiles = GetSinglePathName(szAllFileNames,
- -1, NULL, 0);
- else
- wNumFiles = 0;
- SendMessage(hWnd, UM_UPDATECAPTION, wNumFiles, 0);
- break;
-
- case UM_UPDATECAPTION:
- // Update the window's caption to reflect the # of
- // selected files
- wsprintf(szBuf, "%s - %d file(s) to drop",
- (LPSTR) _szAppName, wParam);
- SetWindowText(hWnd, szBuf);
- break;
-
- case WM_LBUTTONDOWN:
- // User has initiated the "Drag and Drop" sequence
-
- // Make sure that there are some selected files
- // to be dropped
- wNumFiles = GetSinglePathName(szAllFileNames, -1,
- NULL, 0);
- if (wNumFiles == 0)
- {
- MessageBox(hWnd, "No files to drop.",
- _szAppName, MB_OK);
- break;
- }
-
- // Get the handles to the cursors that
- // will shown to the user.
- hCrsrDrpNotAllow = LoadCursor(_hInstance,
- "DRPFIL_NOTALLOWED");
- hCrsrDrpSingle = LoadCursor(_hInstance,
- "DRPFIL_SINGLE");
- hCrsrDrpMultiple = LoadCursor(_hInstance,
- "DRPFIL_MULTIPLE");
-
-
- // *** Loop for determining the drop-file
- // client window ***
- SetCapture(hWnd);
- do {
- // Get cursor pos. & window under the cursor
- GetCursorPos(&ptMousePos);
- hWndSubject = WindowFromPoint(ptMousePos);
-
- if (!IsWindow(hWndSubject) ||
- !(GetWindowLong(hWndSubject, GWL_EXSTYLE) &
- WS_EX_ACCEPTFILES))
- {
- fOkToDrop = FALSE;
- SetCursor(hCrsrDrpNotAllow);
- }
- else
- {
- fOkToDrop = TRUE;
- SetCursor((wNumFiles > 1) ?
- hCrsrDrpMultiple : hCrsrDrpSingle);
- }
-
- // Terminate loop when mouse button is released
- } while (GetAsyncKeyState(VK_LBUTTON) & 0x8000);
- ReleaseCapture();
-
- // Free the loaded cursors from memory
- DestroyCursor(hCrsrDrpNotAllow);
- DestroyCursor(hCrsrDrpSingle);
- DestroyCursor(hCrsrDrpMultiple);
-
-
- if (!fOkToDrop) break;
-
- // Is the cursor in the window's non-client area?
- fInNonClientArea = (HTCLIENT !=
- SendMessage(hWndSubject, WM_NCHITTEST, 0,
- (LONG) MAKELONG(ptMousePos.x, ptMousePos.y)));
-
-
- // Create drop-file memory block and initialize it
- ScreenToClient(hWndSubject, &ptMousePos);
- hDrop = DragCreateFiles(&ptMousePos, fInNonClientArea);
- if (hDrop == NULL)
- {
- MessageBox(hWnd,
- "Insufficient memory to drop file(s).",
- _szAppName, MB_OK);
- break;
- }
-
-
- // *** Append each full pathname to
- // the drop-file memory block ***
- for (x = 0; x < wNumFiles; x++)
- {
- GetSinglePathName(szAllFileNames, x,
- szDropPathName, sizeof(szDropPathName));
-
- // Append pathname to end of drop-file memory block
- hDropT = DragAppendFile(hDrop, szDropPathName);
-
- if (hDropT == NULL)
- {
- MessageBox(hWnd,
- "Insufficient memory to drop file(s).",
- _szAppName, MB_OK);
- GlobalFree(hDrop);
- hDrop = NULL;
- break; // Terminate while loop
- }
- else
- {
- hDrop = hDropT;
- }
- }
-
- if (hDrop != NULL)
- {
- // All pathnames appended successfully,
- // post the message
- // to the drop-file client window
- PostMessage(hWndSubject, WM_DROPFILES, hDrop, 0L);
-
- // Clear our own state
- szAllFileNames[0] = 0;
- SendMessage(hWnd, UM_UPDATECAPTION, 0, 0);
-
- // Don't free the memory,
- // the Dropfile client will do it
- }
- break;
-
- default:
- fCallDefProc = TRUE;
- break;
- }
-
- if (fCallDefProc)
- lResult = DefWindowProc(hWnd, Msg, wParam, lParam);
-
- return(lResult);
- }
-
-
- /****************************************************************************/
- /********************** **************************/
- /********************** FILE OPEN UTILITY FUNCTION **************************/
- /********************** **************************/
- /****************************************************************************/
-
- WORD FAR GetSinglePathName (LPCSTR szFileOpenStr, WORD wIndex,
- LPSTR szPathName, WORD wMaxLen)
- {
-
- WORD wNumFiles = 0, x, y;
- LPCSTR p = szFileOpenStr, q;
- char szBuf[200];
-
- // Initialize the buffer by clearing it
- _fmemset(szBuf, 0, sizeof(szBuf));
-
- // Calculate the number of files in szFileOpenStr
- while (*p)
- {
- if (*p == ' ') wNumFiles++;
- p++;
- }
-
- // If a single file was selected, there are no spaces but we
- // should return that one file exists
- if ((wNumFiles == 0) && (p != szFileOpenStr))
- wNumFiles = 1;
-
- // If the user only wants the number of files, return that
- if ((int) wIndex == -1)
- return(wNumFiles);
-
- // User requested more files than exist
- if (wIndex > wNumFiles)
- return(0);
-
- // *** Construct the full pathname of the requested string ***
- if ((wIndex == 0) && (wNumFiles == 1))
- {
- _fstrncpy(szBuf, szFileOpenStr, wMaxLen);
- }
- else
- {
- // Copy the path portion of the string into a temp buffer
- x = (WORD) ((p = _fstrchr(szFileOpenStr, ' ')) - szFileOpenStr);
- _fstrncpy(szBuf, szFileOpenStr, x);
-
- // Append a backslash if necessary
- if (*(p - 1) != '\\')
- {
- szBuf[x] = '\\';
- x++;
- }
-
- for (y = 0; y < wIndex; y++)
- {
- p++; // Increment past the space, 'p' points to proper filename
- while (*p != ' ') p++;
- }
- p++; // Increment past the space, 'p' points to proper filename
-
- // Find the end of the filename
- q = _fstrchr(p, ' ');
-
- if (q != NULL)
- {
- // Copy the filename into the temp buffer
- _fstrncpy(&szBuf[x], p, (WORD) (q - p));
- }
- else
- {
- // Copy the filename (remainder of string) into the temp buffer
- _fstrcpy(&szBuf[x], p);
- }
- }
-
- if (szPathName != NULL)
- {
- // If the user passed an address, copy the string into its buffer
- _fstrncpy(szPathName, szBuf, wMaxLen);
- szPathName[wMaxLen - 1] = 0; // Force zero-termination
- }
-
- return(lstrlen(szBuf)); // Returns length of string
- }
-
-
-
-
- /****************************************************************************/
- /********************** **************************/
- /********************** DROP-FILE SERVER FUNCTIONS **************************/
- /********************** **************************/
- /****************************************************************************/
-
- typedef struct {
- WORD wSize; // Size of data structure
- POINT ptMousePos; // Position of mouse cursor
- BOOL fInNonClientArea; // Was the mouse in the
- // window's non-client area
- } DROPFILESTRUCT, FAR *LPDROPFILESTRUCT;
-
-
- HDROP FAR DragCreateFiles (LPPOINT lpptMousePos,
- BOOL fInNonClientArea)
- {
-
- HGLOBAL hDrop;
- LPDROPFILESTRUCT lpDropFileStruct;
-
- // GMEM_SHARE must be specified because the block will
- // be passed to another application
- hDrop = GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE | GMEM_ZEROINIT,
- sizeof(DROPFILESTRUCT) + 1);
-
- // If unsuccessful, return NULL
- if (hDrop == NULL) return(hDrop);
-
- // Lock block and initialize the data members
- lpDropFileStruct = (LPDROPFILESTRUCT) GlobalLock(hDrop);
- lpDropFileStruct->wSize = sizeof(DROPFILESTRUCT);
- lpDropFileStruct->ptMousePos = *lpptMousePos;
- lpDropFileStruct->fInNonClientArea = fInNonClientArea;
- GlobalUnlock(hDrop);
- return(hDrop);
- }
-
-
- HDROP FAR DragAppendFile (HGLOBAL hDrop, LPCSTR szPathname)
- {
- LPDROPFILESTRUCT lpDropFileStruct;
- LPCSTR lpCrnt;
- WORD wSize;
-
- lpDropFileStruct = (LPDROPFILESTRUCT) GlobalLock(hDrop);
-
- // Point to first pathname in list
- lpCrnt = (LPSTR) lpDropFileStruct + lpDropFileStruct->wSize;
-
- // Search for a pathname were first byte is a zero byte
- while (*lpCrnt) // While the 1st char of path is non-zero
- {
- while (*lpCrnt) lpCrnt++; // Skip to zero byte
- lpCrnt++;
- }
-
- // Calculate current size of block
- wSize = (WORD) (lpCrnt - (LPSTR) lpDropFileStruct + 1);
- GlobalUnlock(hDrop);
-
- // Increase block size to accommodate new pathname being appended
- hDrop = GlobalReAlloc(hDrop, wSize + lstrlen(szPathname) + 1,
- GMEM_MOVEABLE | GMEM_ZEROINIT | GMEM_SHARE);
-
- // Return NULL if insufficient memory
- if (hDrop == NULL) return(hDrop);
-
- lpDropFileStruct = (LPDROPFILESTRUCT) GlobalLock(hDrop);
- // Append the pathname to the block
- lstrcpy((LPSTR) lpDropFileStruct + wSize - 1, szPathname);
- GlobalUnlock(hDrop);
- return(hDrop); // Return the new handle to the block
- }